Working with PUT, PATCH, and DELETE Operations in Android
Course: Android App Development
Topic: Working with PUT, PATCH, and DELETE Operations
Course Link: Android App Development Training
Demo Link: Register for a Course Demo
Website: JustAcademy
1. Introduction to PUT, PATCH, and DELETE
Modern Android applications frequently communicate with remote servers to create, retrieve, update, and delete information. These operations are commonly implemented using HTTP methods through REST APIs.
PUT, PATCH, and DELETE are important HTTP methods used when an application needs to modify existing resources or remove resources from a server.
For example, in a task management application, users may update all the details of a task, change only its completion status, or delete the task completely.
- PUT: Replaces the current representation of a resource with the supplied representation.
- PATCH: Applies partial modifications to an existing resource.
- DELETE: Requests the removal of a specified resource.
The exact behavior depends on the API contract, particularly how the server validates requests, handles missing fields, and responds to successful operations.
2. Learning Objectives
After studying this topic, learners should be able to:
- Understand the purpose of PUT, PATCH, and DELETE.
- Differentiate between complete and partial updates.
- Configure Retrofit for HTTP requests in Kotlin.
- Send JSON request bodies to a REST API.
- Handle HTTP response codes and exceptions.
- Update RecyclerView after modifying or deleting records.
- Implement loading indicators and user feedback.
- Understand authentication, validation, and API security.
- Test update and delete operations using API testing tools.
3. Understanding HTTP Methods
HTTP methods describe the intended operation for a resource. In REST-style applications, a resource is typically identified by a URL.
| Method |
Purpose |
Example Endpoint |
| GET |
Retrieve information. |
/tasks/10 |
| POST |
Create a resource or submit data for processing. |
/tasks |
| PUT |
Replace a resource representation. |
/tasks/10 |
| PATCH |
Partially modify a resource. |
/tasks/10 |
| DELETE |
Delete a specified resource. |
/tasks/10 |
In this example, the ID 10 identifies the task being updated or deleted. The API server determines whether the requested operation is allowed and how the resource is stored.
4. Understanding the PUT Method
4.1 What Is PUT?
PUT is an HTTP method used to create or replace the state of a resource at a known URL, depending on the server's implementation. When replacing an existing resource, the client generally sends the complete representation required by the API.
For example, consider a task containing the following properties:
{
"id": 10,
"title": "Learn Android",
"description": "Study Retrofit",
"completed": false
}
If the user changes the title and description, a PUT request may send all the fields required by the endpoint.
4.2 Example PUT Request
PUT /tasks/10
Content-Type: application/json
{
"title": "Learn Android Development",
"description": "Study Retrofit and REST APIs",
"completed": false
}
The server processes the supplied representation according to its API contract. If required fields are omitted, the server might reject the request, apply defaults, or treat missing fields according to its own rules.
4.3 When Should PUT Be Used?
- Updating the complete details of a user profile.
- Replacing an existing product record.
- Saving a complete task representation.
- Submitting all editable settings for a resource.
5. Understanding the PATCH Method
5.1 What Is PATCH?
PATCH is used to apply partial modifications to an existing resource. Instead of sending every property, the client sends only the changes supported by the API.
Suppose a task has the following current data:
{
"id": 10,
"title": "Learn Android",
"description": "Study Retrofit",
"completed": false
}
If the user only marks the task as completed, the request may contain just one field.
5.2 Example PATCH Request
PATCH /tasks/10
Content-Type: application/json
{
"completed": true
}
The server applies the requested change while preserving the other fields, provided that the API defines this partial-update behavior.
5.3 PATCH Request Formats
PATCH does not define one universal JSON format. APIs may accept ordinary JSON objects or standardized formats such as JSON Merge Patch or JSON Patch.
- Application-specific JSON: The server defines which fields can be changed.
- JSON Merge Patch: Uses the media type
application/merge-patch+json and defines how supplied members modify an object.
- JSON Patch: Uses the media type
application/json-patch+json and describes changes through operations such as add, remove, and replace.
Always follow the request format documented by the backend. A PATCH endpoint may not accept arbitrary JSON or every field in the resource.
6. Difference Between PUT and PATCH
| Feature |
PUT |
PATCH |
| Main purpose |
Replace a resource representation. |
Apply partial modifications. |
| Request body |
Usually includes the complete representation required by the endpoint. |
Contains the changes in the API's supported patch format. |
| Typical example |
Update all profile details. |
Change only the profile photo URL. |
| Idempotency |
Defined as idempotent by HTTP semantics. |
Can be idempotent, depending on the patch operation and API design. |
| Risk |
Missing fields may cause validation errors or unintended replacement behavior. |
Incorrect patch format or field handling may produce unexpected changes. |
7. Understanding the DELETE Method
7.1 What Is DELETE?
DELETE requests the removal of the resource identified by the request URL. The server determines whether the caller has permission to delete it and how the deletion is carried out.
For example, a task management application may delete task ID 10 using the following request:
DELETE /tasks/10
A successful response may return HTTP 200 with a response body, HTTP 202 if deletion has been accepted for processing, or HTTP 204 when the operation succeeds without a response body.
7.2 When Should DELETE Be Used?
- Removing a task from a task management application.
- Deleting a saved address.
- Removing a product from an authorized inventory system.
- Deleting an item from a user's saved collection.
Some systems use soft deletion, where a record is marked inactive instead of physically removed. The Android client should follow the backend's documented behavior.
8. Setting Up Retrofit in Android
Retrofit is a type-safe HTTP client that makes it easier to define and execute REST API requests. It supports HTTP method annotations, request parameters, request bodies, and response conversion.
Add compatible Retrofit, JSON converter, and coroutine dependencies to the application module's Gradle file. Exact versions should be selected according to the project setup.
Example dependencies:
dependencies {
implementation("com.squareup.retrofit2:retrofit:VERSION")
implementation("com.squareup.retrofit2:converter-gson:VERSION")
}
Replace VERSION with the actual compatible version numbers. The example below uses Gson for JSON serialization and deserialization.
9. Creating the Data Model
Suppose the application manages tasks with an ID, title, description, and completion status.
data class Task(
val id: Int,
val title: String,
val description: String,
val completed: Boolean
)
For complete updates, create a request model containing the fields required by the endpoint.
data class UpdateTaskRequest(
val title: String,
val description: String,
val completed: Boolean
)
For a simple PATCH API that accepts a completion-status field, use a dedicated request model.
data class UpdateTaskStatusRequest(
val completed: Boolean
)
Using separate request models helps avoid sending fields that the endpoint does not require. The property names and data types must match the API contract.
10. Defining PUT, PATCH, and DELETE Endpoints
Retrofit uses annotations to specify HTTP methods and URL paths.
interface TaskApiService {
@PUT("tasks/{id}")
suspend fun updateTask(
@Path("id") id: Int,
@Body request: UpdateTaskRequest
): Task
@PATCH("tasks/{id}")
suspend fun updateTaskStatus(
@Path("id") id: Int,
@Body request: UpdateTaskStatusRequest
): Task
@DELETE("tasks/{id}")
suspend fun deleteTask(
@Path("id") id: Int
): Response<Void>
}
This example assumes that the PUT and PATCH endpoints return a Task JSON object and that DELETE may return an empty response. Adjust the return types according to the real API. For example, a 204 response should not be parsed as a Task object.
The @Path annotation inserts the resource ID into the URL, while @Body serializes a request object using the configured converter.
11. Creating a Retrofit Instance
Create a Retrofit instance using the API's base URL. The base URL must be valid and should end with a slash.
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(
GsonConverterFactory.create()
)
.build()
val taskApi = retrofit.create(
TaskApiService::class.java
)
Replace the example URL with your actual backend URL. Add the Internet permission to the Android manifest when needed:
<uses-permission
android:name="android.permission.INTERNET" />
For production applications, use HTTPS and configure authentication securely where required.
12. Implementing a PUT Request
The following example updates a task by sending the complete request representation.
suspend fun updateTaskDetails(
taskId: Int,
title: String,
description: String,
completed: Boolean
): Task {
val request = UpdateTaskRequest(
title = title,
description = description,
completed = completed
)
return taskApi.updateTask(taskId, request)
}
Call this suspend function from a coroutine or another appropriate asynchronous context. The application should validate the input before sending the request.
After a successful update, refresh the displayed task using the returned resource or the updated data from the repository.
13. Implementing a PATCH Request
PATCH is useful when the user changes only one property of a resource. For example, marking a task as completed should not require resubmitting its title and description if the API supports partial updates.
suspend fun markTaskCompleted(
taskId: Int,
completed: Boolean
): Task {
val request = UpdateTaskStatusRequest(
completed = completed
)
return taskApi.updateTaskStatus(
taskId,
request
)
}
This function assumes the server accepts the JSON object containing completed and returns the updated Task. If the server expects a different patch format or returns no body, change the request or response type accordingly.
14. Implementing a DELETE Request
The following function requests deletion of a task by its ID.
suspend fun deleteTask(taskId: Int) {
val response = taskApi.deleteTask(taskId)
if (!response.isSuccessful) {
throw HttpException(response)
}
}
The response's success status should be checked before removing the corresponding item from the UI. If deletion fails, preserve the current list and display an appropriate message.
For a DELETE endpoint returning HTTP 204, the client should not expect a response body. If the server uses a different response contract, configure the Retrofit method accordingly.
15. Handling API Responses and HTTP Status Codes
HTTP status codes help determine whether a request succeeded or failed.
| Status Code |
Meaning |
Typical Client Action |
| 200 OK |
Request succeeded. |
Read the response body when provided. |
| 202 Accepted |
Request accepted for processing. |
Show pending status if processing is asynchronous. |
| 204 No Content |
Request succeeded without a response body. |
Update the UI without trying to parse a body. |
| 400 Bad Request |
Request is invalid. |
Review the payload and show validation feedback. |
| 401 Unauthorized |
Authentication is missing or invalid. |
Refresh credentials or request sign-in as appropriate. |
| 403 Forbidden |
The caller is not permitted to perform the operation. |
Display a permission-related message. |
| 404 Not Found |
The resource may not exist. |
Refresh the list or explain that the record is unavailable. |
| 409 Conflict |
The operation conflicts with current resource state. |
Resolve the conflict or refresh the data. |
| 422 Unprocessable Content |
The server cannot process the submitted content. |
Show field-level validation errors when available. |
| 500 Internal Server Error |
The server encountered an error. |
Display a retry option where appropriate. |
Not every API uses every status code. Always follow the server's documentation and inspect its error response when troubleshooting.
16. Handling Errors with Kotlin Coroutines
Network operations can fail because of connectivity problems, timeouts, server errors, authentication failures, or invalid responses. Use exception handling to keep the application responsive and provide useful feedback.
try {
val updatedTask = taskApi.updateTask(
taskId,
request
)
// Update the UI with updatedTask.
} catch (exception: IOException) {
// Network or connection failure.
} catch (exception: HttpException) {
// HTTP response indicates a failure.
} catch (exception: Exception) {
// Handle other unexpected errors.
}
This example assumes the API method returns a Task directly. When Retrofit uses a direct suspend return type, unsuccessful HTTP responses commonly result in an HttpException. If the method returns Response<T>, inspect isSuccessful and the status code instead.
17. Updating RecyclerView After PUT or PATCH
When a PUT or PATCH request succeeds, the corresponding item should reflect the updated information. One approach is to replace the item in the current list with the returned resource and submit the new list to a ListAdapter.
fun replaceTaskInList(
currentTasks: List<Task>,
updatedTask: Task
): List<Task> {
return currentTasks.map { task ->
if (task.id == updatedTask.id) {
updatedTask
} else {
task
}
}
}
Submit the returned list to the adapter:
val updatedList = replaceTaskInList(
currentTasks,
updatedTask
)
taskAdapter.submitList(updatedList)
For database-backed applications, update the local database after the server confirms the change, then let the database observer refresh the list. This keeps the database and displayed UI synchronized.
18. Updating RecyclerView After DELETE
After a successful delete response, remove the deleted item from the displayed collection or update the database so that the observer emits the new list.
fun removeTaskFromList(
currentTasks: List<Task>,
deletedTaskId: Int
): List<Task> {
return currentTasks.filterNot {
it.id == deletedTaskId
}
}
After the server confirms the deletion:
val updatedList = removeTaskFromList(
currentTasks,
deletedTaskId
)
taskAdapter.submitList(updatedList)
Do not permanently remove an item from the UI before confirming success unless the application implements a deliberate optimistic-update strategy with rollback support.
19. Using a ViewModel for Update and Delete Operations
A ViewModel can manage the state of update and delete requests while keeping network logic separate from Activity or Fragment code.
class TaskViewModel(
private val repository: TaskRepository
) : ViewModel() {
private val _message = MutableStateFlow<String?>(null)
val message: StateFlow<String?> = _message
fun deleteTask(taskId: Int) {
viewModelScope.launch {
try {
repository.deleteTask(taskId)
_message.value = "Task deleted successfully"
} catch (exception: IOException) {
_message.value = "Check your internet connection"
} catch (exception: HttpException) {
_message.value = "Unable to delete the task"
}
}
}
}
This is a simplified example. The repository should call the API and update the local database when appropriate. A production implementation should also expose loading state, prevent duplicate submissions, and distinguish errors that require different user actions.
20. Authentication and Request Headers
Many update and delete endpoints require authentication. Retrofit can send an authorization header as part of a request.
@PATCH("tasks/{id}")
suspend fun updateTaskStatus(
@Header("Authorization") authorization: String,
@Path("id") id: Int,
@Body request: UpdateTaskStatusRequest
): Task
The authorization value depends on the backend's authentication scheme. For a bearer-token API, it commonly has the format Bearer your_access_token.
For applications with many authenticated endpoints, an OkHttp interceptor can attach the authorization header centrally. Store credentials securely and never hardcode real access tokens in source code.
21. Common Problems and Troubleshooting
| Problem |
Possible Cause |
Solution |
| PUT request fails validation. |
Required fields are missing or have incorrect types. |
Check the API schema and send the expected representation. |
| PATCH updates the wrong fields. |
Incorrect patch format or property names. |
Follow the endpoint's partial-update contract. |
| DELETE returns 404. |
The resource does not exist or the endpoint URL is incorrect. |
Verify the ID and URL path. |
| 401 response occurs. |
Missing, invalid, or expired credentials. |
Check authentication and token refresh behavior. |
| 204 response causes parsing errors. |
The client expects a response body when none is returned. |
Use an appropriate empty-response type. |
| RecyclerView shows old data. |
The adapter or database is not updated. |
Submit a new list or update the database after success. |
| Repeated delete requests occur. |
The action button remains enabled during the request. |
Disable the action while the request is in progress. |
| App freezes during requests. |
Blocking network work runs on the main thread. |
Use asynchronous networking with coroutines. |
22. Best Practices
- Use PUT when replacing a resource representation and PATCH when applying supported partial changes.
- Use DELETE only for the intended resource and confirm the server's response.
- Follow the API documentation for request body formats and response types.
- Validate user input before submitting update requests.
- Handle loading, success, and error states consistently.
- Use coroutines and a ViewModel to separate UI and networking logic.
- Update the local database only according to the application's synchronization strategy.
- Prevent duplicate update and delete actions while requests are in progress.
- Use HTTPS and appropriate authentication and authorization.
- Test error responses and empty response bodies as well as successful responses.
23. Practical Project: Task Management Application
Objective: Build an Android application that lets users update, partially modify, and delete tasks through a REST API.
Project Requirements
- Create a Task data model with an ID, title, description, and completion status.
- Configure Retrofit and create a TaskApiService interface.
- Implement a PUT request to update all task fields.
- Implement a PATCH request to change only the completion status.
- Implement a DELETE request to remove a task.
- Use a repository and ViewModel to manage operations.
- Display tasks in RecyclerView.
- Update the displayed list after successful operations.
- Display loading indicators and error messages.
- Test invalid IDs, network failures, and authorization errors.
Expected result: Users can edit complete task details, change individual fields, and delete tasks while the list remains consistent with the server's data.
24. Interview Questions and Answers
Q1. What is the PUT method?
Answer: PUT requests replacement of a resource representation at a specified URL. Depending on the API design, it can also create a resource at that URL if it does not exist.
Q2. What is the PATCH method?
Answer: PATCH applies partial modifications to a resource using a patch format supported by the server.
Q3. What is the difference between PUT and PATCH?
Answer: PUT generally replaces the resource representation, while PATCH applies specified changes without requiring the entire representation.
Q4. What is the purpose of DELETE?
Answer: DELETE requests removal of a resource identified by a URL.
Q5. Are PUT and DELETE idempotent?
Answer: Both are defined as idempotent HTTP methods. Repeating the same intended request should have the same intended effect on server state, although the response status or body may differ between requests.
Q6. Is PATCH always idempotent?
Answer: No. PATCH can be idempotent when the operation is designed that way, but idempotency depends on the specific patch instructions and server implementation.
Q7. How does Retrofit implement PUT and PATCH?
Answer: Retrofit provides annotations such as @PUT and @PATCH, along with @Path for URL parameters and @Body for request data.
Q8. How should an application handle a 204 response?
Answer: Treat it as a successful response without a body. Do not attempt to deserialize an object that the server did not return.
Q9. How do you update RecyclerView after a successful PUT request?
Answer: Replace the corresponding item with the returned or confirmed updated data and submit the new list to the adapter. A database-backed application can update Room and observe the new results.
Q10. Why should network requests not run on the main thread?
Answer: Network operations may take an unpredictable amount of time. Running them on the main thread can make the UI unresponsive and cause application-not-responding errors.
Q11. What is the role of the repository?
Answer: The repository centralizes data operations and separates API communication, local database updates, and data synchronization from the UI layer.
Q12. What should happen if a DELETE request fails?
Answer: The application should retain or restore the item, show a suitable error message, and offer retry when appropriate.
25. Quick Revision
- PUT replaces a resource representation.
- PATCH applies partial modifications.
- DELETE requests removal of a resource.
- PUT and DELETE are idempotent by HTTP definition.
- PATCH idempotency depends on the operation.
- Retrofit provides annotations for these HTTP methods.
- @Path identifies the resource in the URL.
- @Body sends serialized request data.
- HTTP status codes help determine the result of a request.
- Coroutines support asynchronous API calls.
- RecyclerView should reflect successful server-side changes.
- Authentication, validation, and error handling are essential.
Conclusion
PUT, PATCH, and DELETE are essential HTTP methods for building Android applications that modify remote data. PUT is appropriate for replacing a resource representation, PATCH is suitable for supported partial changes, and DELETE requests resource removal.
By combining Retrofit, Kotlin coroutines, ViewModel, repository patterns, and RecyclerView, developers can create applications that perform these operations efficiently and provide clear feedback to users. Always follow the backend API contract, handle unsuccessful responses, and keep local and remote data consistent.
Additional Learning Resources
HTTP Request Methods Reference
Android Developers: Connecting to the Network
Retrofit: Request Method Declarations
Explore Android App Development Training at JustAcademy
Register for a Course Demo
Visit JustAcademy